package com.chongdong.service;

import com.alibaba.fastjson.JSON;
import com.chongdong.Constants;
import com.chongdong.dao.huali.mapper.*;
import com.chongdong.dao.local.mapper.*;
import com.chongdong.entity.huali.*;
import com.chongdong.entity.local.*;
import com.chongdong.entity.saas.PrdCategory;
import com.chongdong.util.NameUtils;
import com.chongdong.util.ThreadPoolUtil;
import com.github.pagehelper.PageHelper;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class HuaLiServiceImpl {
    @Autowired
    private HuaLiSysProviderMapper hualiSysProviderMapper;
    @Autowired
    private HuaLiPrdBaseMapper hualiPrdBaseMapper;
    @Autowired
    private HuaLiPrdBrandMapper hualiPrdBrandMapper;
    @Autowired
    private HuaLiPrdCategoryMapper hualiPrdCategoryMapper;
    @Autowired
    private HuaLiPrdDetailMapper hualiPrdDetailMapper;
    @Autowired
    private HuaLiPrdImagesMapper hualiPrdImagesMapper;
    @Autowired
    private HuaLiPrdBrandProvMapper huaLiPrdBrandProvMapper;
    @Autowired
    private LocalPrdBrandMapper localPrdBrandMapper;
    @Autowired
    private LocalSysProviderMapper localSysProviderMapper;
    @Autowired
    private LcoalPrdCategoryMapper lcoalPrdCategoryMapper;
    @Autowired
    private LocalPrdBaseMapper localPrdBaseMapper;
    @Autowired
    private LocalPrdDetailMapper localPrdDetailMapper;
    @Autowired
    private LocalPrdImagesMapper localPrdImagesMapper;
    @Autowired
    private LocalPrdBrandProvMapper localPrdBrandProvMapper;
    private final static Logger logger = LoggerFactory.getLogger(HuaLiServiceImpl.class);


    /**
     * 将商家数据合并到saas平台,总体合并逻辑为saas上存在则更新本地系统saas_id,不存在则保存至saas平台，同时更新本地系统saas_id,
     * 供应商去重以name为基准
     */
    public void transferProviderHuaLiData2SaaSPlatform() throws Exception {

        Map<String, Long> collect = localSysProviderMapper.selectAll().
                stream().collect(
                Collectors.toMap(LocalSysProvider::getName, LocalSysProvider::getId)
        );
        //1.查询所有数据
        List<HuaLiSysProvider> sysProviders = hualiSysProviderMapper.selectWithSaasIdIsNull();
        Date createTime = new Date();
        Date updateTime = new Date();
        //2.将所有数据导入数据库
        sysProviders.forEach(p -> {
            //获取最终统一名称
            p.setName(NameUtils.getFinalSysProviderName(p.getName(), NameUtils.HUALI));
            if (collect.get(p.getName()) != null) {//已经存在
                if (Constants.ISUPDATE) {
                    p.setSaasPrvId(collect.get(p.getName()));
                    hualiSysProviderMapper.updateByPrimaryKeySelective(p);
                }
                LocalSysProvider s = new LocalSysProvider();
                s.setId(p.getSaasPrvId());
                s.setBankBranchCode(p.getBankBranchCode());
                localSysProviderMapper.updateByPrimaryKeySelective(s);
            } else {
                //对象转换
                LocalSysProvider localSysProvider = copyHuaLiProviderValue(p, createTime, updateTime);
                int i = localSysProviderMapper.insertSelective(localSysProvider);
                collect.put(p.getName(), localSysProvider.getId());
                if (i > 0 && Constants.ISUPDATE) {
                    p.setSaasPrvId(localSysProvider.getId());
                    hualiSysProviderMapper.updateByPrimaryKeySelective(p);
                }
            }
            //保存协议信息
            try {
                saveByrProtocolInfo(collect.get(p.getName()));
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    @Transactional(value = "localTransactionManager")
    public void saveByrProtocolInfo(Long prvId) throws Exception {
        //同步协议供应商信息，对应byr_protocol_provider表
        localSysProviderMapper.insertByrProtocalProvider(Constants.HUALIORGID, prvId,
                Constants.prvType, Constants.providerStatus, new Date(), new Date());

        //同步买家(企业)协议供货商表byr_protocol
        localSysProviderMapper.insertbyrProtocol(Constants.HUALIORGID, prvId,
                "hualiLine" + prvId, Constants.protocolStatus, Constants.protocalType, Constants.protocolRate);
    }

    /**
     * 将品牌数据合并到saas平台,总体合并逻辑为saas上存在则更新本地系统saas_id,不存在则保存至saas平台，同时更新本地系统saas_id,
     * 品牌去重以品牌name为基准
     */
    public void trnansferBrandData2SaasPlatform() throws Exception {
        Map<String, Long> collect = localPrdBrandMapper.selectAll().stream().
                collect(Collectors.toMap(LocalPrdBrand::getName, LocalPrdBrand::getId));
        //查询所有数据
        List<HuaLiPrdBrand> prdBrands = hualiPrdBrandMapper.selectAllWithSaasIdIsNull();
        //2.将数据导入数据库
        LocalPrdBrand localPrdBrand = new LocalPrdBrand();
        prdBrands.forEach(p -> {
            if (collect.get(NameUtils.getFinalPrdBrandName(p.getName(), NameUtils.HUALI)) != null) {
                p.setSaasBrandId(collect.get(NameUtils.getFinalPrdBrandName(p.getName(), NameUtils.HUALI)));
                p.setNameEn(NameUtils.getFinalPrdBrandNameEn(p.getName(), NameUtils.HUALI));
                p.setName(NameUtils.getFinalPrdBrandName(p.getName(), NameUtils.HUALI));
                hualiPrdBrandMapper.updateByPrimaryKeySelective(p);
            } else {
                try {
                    BeanUtils.copyProperties(localPrdBrand, p);
                } catch (Exception e) {
                    logger.error("当前执行到的记录是华理合并品牌" + p.getId());
                    logger.error(e.toString());
                    throw new RuntimeException("转换失败");
                }
                localPrdBrand.setId(null);
                //获取最终名称
                localPrdBrand.setName(NameUtils.getFinalPrdBrandName(p.getName(), NameUtils.HUALI));
                localPrdBrand.setNameEn(NameUtils.getFinalPrdBrandNameEn(p.getName(), NameUtils.HUALI));
                localPrdBrandMapper.insertSelective(localPrdBrand);
                //补充添加新元素
                collect.put(localPrdBrand.getName(), localPrdBrand.getId());
                if (Constants.ISUPDATE) {
                    p.setSaasBrandId(localPrdBrand.getId());
                    p.setNameEn(localPrdBrand.getNameEn());
                    p.setName(localPrdBrand.getName());
                    hualiPrdBrandMapper.updateByPrimaryKeySelective(p);
                }
            }
        });
    }


    /**
     * 将类目信息合并到saas平台，药生所默认覆盖更新saas上的数据，药生所prd_category对应的saas_id全部更新药生所本地系统对应id
     */
    public void transferCategoryData2Platform() throws Exception {
        Map<String, Long> collect = lcoalPrdCategoryMapper.selectAll().stream().
                collect(Collectors.toMap(LocalPrdCategory::getName, LocalPrdCategory::getId));

        LocalPrdCategory localPrdCategory = new LocalPrdCategory();
        hualiPrdCategoryMapper.selectWithSaasIdIsNUll().forEach(p -> {
            if (collect.get(p.getName()) == null) {//不存在则保存
                try {
                    BeanUtils.copyProperties(localPrdCategory, p);
                } catch (Exception e) {
                    logger.error("当前所处执行阶段是华理<<合并类目>>,发生的异常数据为" + JSON.toJSONString(p) + "错误信息为" + e.toString());
                    e.printStackTrace();
                }
                localPrdCategory.setId(null);
                lcoalPrdCategoryMapper.insertSelective(localPrdCategory);

                collect.put(p.getName(), localPrdCategory.getId());
                //saas_id设置为对应id
                p.setSaasCategoryId(localPrdCategory.getId());
                collect.put(p.getName(), p.getSaasCategoryId());
                hualiPrdCategoryMapper.updateByPrimaryKeySelective(p);

            } else {
                if (Constants.ISUPDATE) {
                    //saas_id设置为对应id
                    p.setSaasCategoryId(collect.get(p.getName()));
                    hualiPrdCategoryMapper.updateByPrimaryKeySelective(p);
                }
            }
        });
    }


    /**
     * 将商品数据合并到saas平台
     */
    public void trnsferProductHuaLiData2SaaSPlatform(Integer pageNum, Integer pageSize) throws Exception {
        pageNum = (pageNum == null ? 1 : pageNum);
        pageSize = (pageSize == null ? 5000 : pageSize);
        Map<Long, Long> brandMap = hualiPrdBrandMapper.selectAll().stream().collect(Collectors.toMap(HuaLiPrdBrand::getId, HuaLiPrdBrand::getSaasBrandId));
        Map<Long, Long> providerMap = hualiSysProviderMapper.selectAll().stream().collect(Collectors.toMap(HuaLiSysProvider::getId, HuaLiSysProvider::getSaasPrvId));
        Map<Long, Long> categoryMap = hualiPrdCategoryMapper.selectAll().stream().collect(Collectors.toMap(HuaLiPrdCategory::getId, HuaLiPrdCategory::getSaasCategoryId));

        while (pageSize > 0) {
            //1.查询所有数据
            PageHelper.startPage(1, pageSize);
            List<HuaLiPrdBase> hualiPrdBases = hualiPrdBaseMapper.selectAllWithSaasIsNUll();
            Date createTime = new Date();
            Date updateTime = new Date();
            //2.将数据导入数据库
            //以华理数据位为基础数据
            hualiPrdBases.forEach(p -> {
                LocalPrdBase localPrdBase = null;
                Long prvId = providerMap.get(p.getPrvId());
                Long protocolId = localPrdBaseMapper.getProtocalId(prvId, Constants.HUALIORGID);
                try {
                    localPrdBase = copyHuaLiPrdBaseValue(p, createTime, updateTime);
                } catch (InvocationTargetException e) {
                    logger.error("当前执行的模块为华理<<合并商品>>当前数据为" + JSON.toJSONString(p));
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    logger.error("当前执行的模块为华理<<合并商品>>当前数据为" + JSON.toJSONString(p));
                    e.printStackTrace();
                }
                //设置商品对应的saas信息
                localPrdBase.setPrvId(providerMap.get(p.getPrvId()));
                localPrdBase.setCategoryId(categoryMap.get(p.getCategoryId()));
                localPrdBase.setBrandId(brandMap.get(p.getBrandId()));
                localPrdBase.setId(null);
                localPrdBaseMapper.insertSelective(localPrdBase);
                if (Constants.ISUPDATE) {
                    p.setSaaSPrdId(localPrdBase.getId());
                    hualiPrdBaseMapper.updateByPrimaryKeySelective(p);
                }
                //同步byr_protocol_product
                localPrdBaseMapper.insertbyrProtocolProduct(protocolId, localPrdBase.getId(), Constants.protocolProductStatus, Constants.protocolProductType, new Date(), new Date(), p.getInitPrice(), p.getDiscount());
            });
            logger.info("当前执行的模块为合并华理的品牌数据，已结束记录页码为" + pageNum);
            pageNum++;
            pageSize = hualiPrdBases.size() == pageSize ? hualiPrdBases.size() : -1;
        }

    }

    /**
     * 更新商品详情信息
     */
    public void trnsferPrdDetailHuaLiData2SaaSPlatform(Integer pageNum, Integer pageSize) throws Exception {
        pageNum = (pageNum == null ? 1 : pageNum);
        pageSize = (pageSize == null ? 5000 : pageSize);
        Map<Long, Long> collect = hualiSysProviderMapper.selectAll().stream().
                collect(Collectors.toMap(HuaLiSysProvider::getId, HuaLiSysProvider::getSaasPrvId));

        while (pageSize > 0) {
            PageHelper.startPage(1, pageSize);
            List<HuaLiPrdDetail> hualiPrdDetails = hualiPrdDetailMapper.selectAllWithSaasId();

            hualiPrdDetails.forEach(detail -> {
                LocalPrdDetail localPrdDetail = new LocalPrdDetail();
                try {
                    BeanUtils.copyProperties(localPrdDetail, detail);
                } catch (Exception e) {
                    logger.error("当前执行的模块为华理更新商品信息，对应的数据为" + JSON.toJSONString(detail));
                    e.printStackTrace();
                }
                localPrdDetail.setPrdId(hualiPrdBaseMapper.selectByPrimaryKey(localPrdDetail.getPrdId()).getSaaSPrdId());
                localPrdDetail.setPrvId(collect.get(localPrdDetail.getPrvId()));
                localPrdDetail.setId(null);
                localPrdDetailMapper.insertSelective(localPrdDetail);
                if (Constants.ISUPDATE) {
                    detail.setSaasPrdId(localPrdDetail.getId());
                    hualiPrdDetailMapper.updateByPrimaryKeySelective(detail);
                }
            });
            logger.info("当前执行的模块为合并华理的品牌详情数据，已结束记录页码为" + pageNum);

            pageNum++;
            pageSize = hualiPrdDetails.size() == pageSize ? hualiPrdDetails.size() : -1;
        }

    }

    /**
     * 更新商品图片信息，
     */
    public void trnsferPrdImageHuaLiData2SaaSPlatform(Integer pageNum, Integer pageSize) {
        pageNum = (pageNum == null ? 1 : pageNum);
        pageSize = (pageSize == null ? 5000 : pageSize);
        while (pageSize > 0) {
            PageHelper.startPage(1, pageSize);
            List<HuaLiPrdImages> hualiPrdImages = hualiPrdImagesMapper.selectAllWithSaasIdIsNull();

            hualiPrdImages.forEach(img -> {
                LocalPrdImages localPrdImages = new LocalPrdImages();
                HuaLiPrdImages images = hualiPrdImagesMapper.getSaasInfoByImgId(img.getId());
                List<LocalPrdImages> select = localPrdImagesMapper.select(new LocalPrdImages(images.getPrdId(), images.getImgUrl(), images.getImgThumbnails()));
                if (select.size() < 1) {
                    try {
                        BeanUtils.copyProperties(localPrdImages, img);
                    } catch (Exception e) {
                        logger.error("当前执行的模块为华理更新商品图片信息，错误信息为" + JSON.toJSONString(img));
                        e.printStackTrace();
                    }
                    localPrdImages.setPrdId(hualiPrdBaseMapper.selectByPrimaryKey(localPrdImages.getPrdId()).getSaaSPrdId());
                    localPrdImages.setId(null);
                    localPrdImagesMapper.insertSelective(localPrdImages);
                    if (Constants.ISUPDATE) {
                        img.setSaasPrdId(localPrdImages.getId());
                        hualiPrdImagesMapper.updateByPrimaryKeySelective(img);
                    }
                } else {
                    if (Constants.ISUPDATE) {
                        img.setSaasPrdId(select.get(0).getId());
                        hualiPrdImagesMapper.updateByPrimaryKeySelective(img);
                    }
                }
            });

            logger.info("当前执行的模块为合并华理的商品图片数据，已结束记录页码为" + pageNum);
            pageNum++;
            pageSize = hualiPrdImages.size() == pageSize ? hualiPrdImages.size() : -1;
        }

    }

    /**
     * 更新商家资质信息prd_brand_prov
     */

    public void transferSysProviderAndBrandRelation() {
        Map<Long, Long> providerMap = hualiSysProviderMapper.selectAll().stream().collect(Collectors.toMap(HuaLiSysProvider::getId, HuaLiSysProvider::getSaasPrvId));
        Map<Long, Long> brandMap = hualiPrdBrandMapper.selectAll().stream().collect(Collectors.toMap(HuaLiPrdBrand::getId, HuaLiPrdBrand::getSaasBrandId));
        List<HuaLiPrdBrandProv> huaLiPrdBrandProvs = huaLiPrdBrandProvMapper.selectAll();
        LocalPrdBrandProv prdBrandProv = new LocalPrdBrandProv();
        huaLiPrdBrandProvs.forEach(p -> {
            LocalPrdBrandProv p0 = new LocalPrdBrandProv();
            p0.setPrvId(providerMap.get(p.getPrvId()));
            p0.setBrandId(brandMap.get(p.getBrandId()));
            if (localPrdBrandProvMapper.select(p0).size() < 1) {
                try {
                    BeanUtils.copyProperties(prdBrandProv, p);
                } catch (IllegalAccessException e) {
                    logger.error("当前执行的模块为华理更新商家资质信息，错误信息为" + JSON.toJSONString(p));
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    logger.error("当前执行的模块为华理更新商家资质信息，错误信息为" + JSON.toJSONString(p));
                    e.printStackTrace();
                }
                prdBrandProv.setPrvId(providerMap.get(p.getPrvId()));
                prdBrandProv.setBrandId(brandMap.get(p.getBrandId()));
                prdBrandProv.setId(null);
                localPrdBrandProvMapper.insertSelective(prdBrandProv);
            }

        });
    }


    /**
     * 转对象
     *
     * @param source
     * @param createTime
     * @param updateTime
     * @return
     */
    public LocalSysProvider copyHuaLiProviderValue(HuaLiSysProvider source, Date createTime, Date updateTime) {
        LocalSysProvider dest = new LocalSysProvider();
        dest.setName(source.getName());
        dest.setAddress(source.getAddress());
        dest.setApproveStatus(source.getStatus());
        dest.setType(source.getType());
        dest.setLogo(source.getLogo());
        dest.setCreateTime(createTime);
        dest.setContact(source.getContact());
        dest.setTelephone(source.getTelephone());
        dest.setEmail(source.getEmail());
        dest.setSysNum(source.getSysNum());
        dest.setStatus(source.getStatus());
        dest.setAreaId(source.getAreaId());
        dest.setShortName(StringUtils.isBlank(source.getShortName()) ? "" : source.getShortName());
        dest.setTaxNo(source.getTaxNo());
        dest.setBank(source.getAcctBank());
        dest.setBankAccount(source.getAccount());
        dest.setLicenseUrl(source.getLicenseUrl());
        dest.setUpdateTime(updateTime);
        dest.setBankBranchCode(source.getBankBranchCode());
        return dest;
    }

    public LocalPrdBase copyHuaLiPrdBaseValue(HuaLiPrdBase source, Date createTime, Date updateTime) throws InvocationTargetException, IllegalAccessException {
        LocalPrdBase localPrdBase = new LocalPrdBase();
        BeanUtils.copyProperties(localPrdBase, source);
        localPrdBase.setId(null);
        localPrdBase.setCreateTime(createTime);
        localPrdBase.setUpdateTime(updateTime);
        return localPrdBase;
    }

}
